// Created by Roman Novitsky on 23.04.2009


#region Imported Namespaces


using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Windows;
using System.Windows.Input;

using AvalonDock;

using WtfManager.Controls;
using WtfManager.Framework;


#endregion


namespace WtfManager.UIManager.Commands
{
  public class ShowPanelCommandHandler: Service, ICommandHandler, IMenuManagerExtension
  {
    #region Fields


    private UIService _uiService;


    #endregion


    #region Constructors/Finalizers


    internal ShowPanelCommandHandler()
    {
    }


    #endregion


    #region Properties/Indexers


    public ICommand Command
    {
      get
      {
        return ViewCommands.ShowPanel;
      }
    }

    public override string Description
    {
      get
      {
        return "Handles ViewCommands.ShowPanel command";
      }
    }


    public override string Name
    {
      get
      {
        return "Show Panel Command Handler";
      }
    }


    #endregion


    #region Methods


    public string GetCommandAlias(object commandParameter)
    {
      UIControlInfo panel = GetPanel(commandParameter);

      if (panel == null)
      {
        return null;
      }

      var attribute = panel.GetAttribute<PanelControlAttribute>();

      return "Show " + attribute.Name;
    }


    public List<object> GetAllPossibleParameters(IInputElement element)
    {
      var parameters = new List<object>();
      List<UIControlInfo> panels = _uiService.GetPanels();

      foreach (UIControlInfo panel in panels)
      {
        parameters.Add(panel.ControlType);
      }

      return parameters;
    }


    protected override void OnStateChnaged()
    {
      if (IsInitialized)
      {
        _uiService = (UIService)WtfFramework.Instance.Services[typeof(UIService)];
      }
      else
      {
        _uiService = null;
      }
    }


    protected override FrameworkComponentState OnLoad()
    {
      AddDependency(typeof(UIService));

      return FrameworkComponentState.Loaded;
    }


    protected override void OnUnload()
    {
    }


    public bool CanExecuteCommand(object sender, object parameter)
    {
      Debug.Assert(IsInitialized, "ShowPanelCommandHandler is not yet initialized.");

      UIControlInfo panel = GetPanel(parameter);

      if (panel == null)
      {
        return false;
      }

      var attribute = panel.GetAttribute<PanelControlAttribute>();

      if (attribute.AllowMultiplePanelsOpen)
      {
        return true;
      }

      DockableContent openPanel = GetOpenPanel(panel);

      return openPanel == null || openPanel.State == DockableContentState.Hidden;
    }


    private UIControlInfo GetPanel(object parameter)
    {
      if (parameter == null || !(parameter is Type))
      {
        return null;
      }

      return _uiService.GetPanel((Type)parameter);
    }


    private static DockableContent GetOpenPanel(UIControlInfo panel)
    {
      DockableContent openPanel = null;

      foreach (DockableContent dockableContent in WtfDockingManager.CurrentDockingManager.DockableContents)
      {
        if (dockableContent.GetType().FullName == panel.ControlType.FullName)
        {
          openPanel = dockableContent;
        }
      }

      return openPanel;
    }


    public void ExecuteCommand(object sender, object parameter)
    {
      Debug.Assert(IsInitialized, "ShowPanelCommandHandler is not yet initialized.");

      UIControlInfo panel = _uiService.GetPanel((Type)parameter);
      DockableContent openPanel = GetOpenPanel(panel) ?? (DockableContent)panel.CreateInstance();

      ShowWindow(openPanel, DockableContentState.FloatingWindow);
    }


    private static void ShowWindow(DockableContent contentToShow, DockableContentState desideredState)
    {
      if (desideredState == DockableContentState.AutoHide || desideredState == DockableContentState.FloatingWindow)
      {
        WtfDockingManager.CurrentDockingManager.Show(contentToShow, desideredState);
      }
      else
      {
        WtfDockingManager.CurrentDockingManager.Show(contentToShow, DockableContentState.Docked);
      }
    }


    protected override FrameworkComponentState OnInitialize()
    {
      return FrameworkComponentState.Initialized;
    }


    #endregion
  }
}